home *** CD-ROM | disk | FTP | other *** search
- /* SCSISimpleSampleDisplay.c */
- /*
- * This module displays the results from all tests. Note that it is
- * intentionally pretty crude so the entire display is described in this file;
- * a "real" program would move strings to resources and, perhaps, more clearly
- * explain the results.
- */
- #include "SCSISimpleSample.h"
-
- typedef struct {
- unsigned char senseKey;
- StringPtr senseText;
- } SenseKeyText;
-
- /*
- * The sense keys.
- */
- static StringPtr gSenseKeyText[] = {
- "\pNo error",
- "\pRecovered error",
- "\pNot ready",
- "\pMedium error",
-
- "\pHardware error",
- "\pIllegal request",
- "\pUnit attention",
- "\pData protection",
-
- "\pBlank check",
- "\pVendor specific",
- "\pCopy aborted",
- "\pCommand aborted",
-
- "\pCompare equal",
- "\pVolume overflow",
- "\pMiscompare",
- "\pReserved"
- };
-
- StringPtr gScsiDeviceType[] = {
- "\pDisk",
- "\pTape",
- "\pPrinter",
- "\pProc.",
- "\pWORM",
- "\pCD-ROM",
- "\pScanner",
- "\pOptical",
- "\pChanger",
- "\pComm.",
- "\pUnknown"
- };
-
- StringPtr gScsiState[] = {
- "\pNot Ready",
- "\pBecoming Ready",
- "\pUnit Attention",
- "\pBusy",
- "\pReady",
- "\pFailure"
- };
-
- typedef struct CmdInfo {
- unsigned short cmdByte;
- StringPtr text;
- } CmdInfo, *CmdInfoPtr;
- static CmdInfo gCmdInfo[] = {
- { kScsiCmdInquiry, "\pInquiry" },
- { kScsiCmdLogSelect, "\pLog Select" },
- { kScsiCmdLogSense, "\pLog Sense" },
- { kScsiCmdModeSelect12, "\pMode Select [12]" },
- { kScsiCmdModeSelect6, "\pMode Select [6]" },
- { kScsiCmdModeSense12, "\pMode Sense [6]" },
- { kScsiCmdRequestSense, "\pRequest Sense" },
- { kScsiCmdTestUnitReady, "\pTest Unit Ready" },
- { kScsiCmdPreventAllowRemoval, "\pPrevent or Allow Removal" },
- { kScsiCmdRead6, "\pRead [6]" },
- { kScsiCmdRead10, "\pRead [10]" },
- { kScsiCmdReadCapacity, "\pRead Device Capacity" },
- { kScsiCmdReadDefectData, "\pRead Defect Data" },
- { kScsiCmdReassignBlocks, "\pReassign Blocks" },
- { kScsiCmdStartStopUnit, "\pStart or Stop Unit" },
- { 0xFF, NULL }
- };
-
-
- /*
- * ShowSCSIBusID is called before sending a command to the indicated device.
- */
- void
- ShowSCSIBusID(
- DeviceIdent scsiDevice, /* -> Bus/target/LUN */
- ConstStr255Param commandText
- )
- {
- Str255 work;
-
- pstrcpy(work, "\pBus ID: ");
- AppendDeviceID(work, scsiDevice);
- if (commandText != NULL) {
- pstrcat(work, "\p, ");
- pstrcat(work, commandText);
- }
- LOG(work);
- }
-
- /*
- * Display the results of an extended sense request.
- * Format the fields we understand.
- */
- void
- ShowRequestSense(
- register ScsiCmdBlockPtr scsiCmdBlockPtr
- )
- {
- #define SCB (*scsiCmdBlockPtr)
- DoShowRequestSense(
- SCB.scsiDevice, /* For this device */
- SCB.status, /* The original error from the SCSI Manager */
- SCB.requestSenseStatus, /* The error, if any, from Request Sense */
- &SCB.command, /* The command that failed */
- &SCB.sense /* -> the sense buffer */
- );
- #undef SCB
- }
-
- /*
- * Actually display the results of a request sense. This is independent of the SCB
- */
- void
- DoShowRequestSense(
- DeviceIdent scsiDevice,
- OSErr operationStatus,
- OSErr requestSenseStatus,
- const SCSI_CommandPtr scsiCommand,
- const SCSI_Sense_Data *sensePtr
- )
- {
- register int i;
- Str255 work;
- Str255 senseMessage;
- #define SENSE (*sensePtr)
-
- if (operationStatus != noErr) {
- ShowSCSIBusID(scsiDevice, "\pOperation failed");
- DoShowSCSICommand(scsiCommand, NULL);
- }
- if (operationStatus != noErr && operationStatus != statusErr) {
- /*
- * The operation failed, and the failure was severe enough that
- * the device didn't return Check Condition. Perhaps there is
- * no device at this bus/target.
- */
- ShowStatusError(scsiDevice, operationStatus, scsiCommand);
- }
- if (operationStatus == statusErr && requestSenseStatus == noErr) {
- /*
- * The operation failed, the device returned Check Condition, and
- * we were able to read the Request Sense information.
- */
- pstrcpy(work, "\pSense: ");
- if ((SENSE.errorCode & kScsiSenseInfoMask) != kScsiSenseInfoValid) {
- AppendPascalString(work, "\p(invalid sense code)");
- AppendHexLeadingZeros(work, SENSE.errorCode, 2);
- LOG(work);
- }
- else {
- AppendPascalString(
- work, gSenseKeyText[SENSE.senseKey & kScsiSenseKeyMask]);
- if ((SENSE.senseKey & kScsiSenseILI) != 0)
- AppendPascalString(work, "\p, Illegal Logical Length");
- if ((SENSE.senseKey & kScsiSenseEOM) != 0)
- AppendPascalString(work, "\p, End of Media");
- if ((SENSE.senseKey & kScsiSenseFileMark) != 0)
- AppendPascalString(work, "\p, File Mark");
- LOG(work);
- work[0] = 0;
- AppendPascalString(work, "\p ASC: ");
- AppendHexLeadingZeros(work, SENSE.additionalSenseCode, 2);
- AppendPascalString(work, "\p, ASQ: ");
- AppendHexLeadingZeros(work, SENSE.additionalSenseQualifier, 2);
- for (i = 1;; ++i) {
- GetIndString(
- senseMessage, SENSE.additionalSenseCode + STRS_SenseBase, i);
- if (senseMessage[0] == 0) {
- /*
- * We don't know the sense qualifier, use the default
- * additional sense code message, if any.
- */
- GetIndString(
- senseMessage,
- SENSE.additionalSenseCode + STRS_SenseBase,
- 1
- );
- if (senseMessage[0] != 0)
- goto displaySense;
- break;
- }
- if (senseMessage[1] == SENSE.additionalSenseQualifier) {
- displaySense: senseMessage[1] = senseMessage[0] - 1;
- AppendPascalString(work, "\p, ");
- AppendPascalString(work, (StringPtr) &senseMessage[1]);
- break;
- }
- }
- LOG(work);
- }
- }
- #undef SENSE
- }
-
- /*
- * This formats and displays the SCSI Manager OSErr code (with out extensions)
- */
- void
- ShowStatusError(
- DeviceIdent scsiDevice,
- OSErr errorStatus,
- const SCSI_CommandPtr scsiCommand
- )
- {
- Str255 work;
- StringHandle errorHdl;
-
- if (errorStatus != noErr || gVerboseDisplay) {
- pstrcpy(work, "\pDevice: ");
- AppendDeviceID(work, scsiDevice);
- AppendPascalString(work, "\p, ");
- switch (errorStatus) {
- case noErr: AppendPascalString(work, "\pSuccessful"); break;
- case scsiNonZeroStatus: /* Continue */
- case statusErr: AppendPascalString(work, "\pCheck Condition"); break;
- case controlErr: AppendPascalString(work, "\pBusy"); break;
- case scBadParmsErr: AppendPascalString(work, "\pParam Error"); break;
- case scCommErr: AppendPascalString(work, "\pNo Device"); break;
- case scPhaseErr: AppendPascalString(work, "\pPhase Error"); break;
- case scComplPhaseErr: AppendPascalString(work, "\pBad Phase"); break;
- default:
- AppendPascalString(work, "\pSystem Error ");
- AppendSigned(work, errorStatus);
- errorHdl = (StringHandle) GetResource('Estr', errorStatus);
- if (errorHdl != NULL) {
- AppendPascalString(work, "\p, \"");
- HLock((Handle) errorHdl);
- AppendPascalString(work, *errorHdl);
- HUnlock((Handle) errorHdl);
- ReleaseResource((Handle) errorHdl);
- AppendPascalString(work, "\p\"");
- }
- break;
- }
- LOG(work);
- DoShowSCSICommand(scsiCommand, NULL);
- }
- }
-
- void
- DoShowInquiry(
- DeviceIdent scsiDevice, /* -> Bus/target/LUN */
- const SCSI_Inquiry_Data *inquiry
- )
- {
- unsigned short i;
- Str255 work;
- #define INQUIRY (*inquiry)
-
- work[0] = 0;
- AppendDeviceID(work, scsiDevice);
- i = INQUIRY.devType;
- if (i > kScsiDevTypeMax)
- i = kScsiDevTypeMax;
- AppendPascalString(work, "\p: \"");
- AppendPascalString(work, gScsiDeviceType[i]);
- AppendPascalString(work, "\p\", \"");
- AppendBytes(work, (const Ptr) INQUIRY.vendor, sizeof INQUIRY.vendor);
- AppendPascalString(work, "\p\", \"");
- AppendBytes(work, (const Ptr) INQUIRY.product, sizeof INQUIRY.product);
- AppendPascalString(work, "\p\", \"");
- AppendBytes(work, (const Ptr) INQUIRY.revision, sizeof INQUIRY.revision);
- AppendPascalString(work, "\p\"");
- LOG(work);
- #undef INQUIRY
- }
-
- void
- DisplaySCSIErrorMessage(
- OSErr errorStatus,
- ConstStr255Param errorText
- )
- {
- Str255 work;
- Handle errorMsgHdl;
-
- if (errorStatus != noErr) {
- pstrcpy(work, "\pSCSI Error (");
- AppendSigned(work, errorStatus);
- AppendPascalString(work, "\p) at ");
- AppendPascalString(work, (const StringPtr) errorText);
- AppendChar(work, '.');
- errorMsgHdl = GetResource('Estr', errorStatus);
- if (errorMsgHdl != NULL) {
- AppendPascalString(work, "\p \"");
- AppendPascalString(work, (StringPtr) *errorMsgHdl);
- AppendPascalString(work, "\p\"");
- ReleaseResource(errorMsgHdl);
- }
- LOG(work);
- }
- }
-
- void
- DoShowSCSICommand(
- const SCSI_CommandPtr scsiCommand,
- ConstStr255Param message
- )
- {
- register CmdInfoPtr cmdInfoPtr;
- register unsigned short i;
- unsigned short cmdBlockLength; /* -> Length of CDB */
- Str255 work;
-
- work[0] = 0;
- if (message != NULL && message[0] != 0) {
- AppendPascalString(work, (StringPtr) message);
- AppendPascalString(work, "\p, ");
- }
- pstrcpy(work, "\pCommand ");
- for (cmdInfoPtr = gCmdInfo; cmdInfoPtr->text != NULL; cmdInfoPtr++) {
- if (cmdInfoPtr->cmdByte == scsiCommand->scsi[0]) {
- AppendPascalString(work, "\p (");
- AppendPascalString(work, cmdInfoPtr->text);
- AppendPascalString(work, "\p)");
- break;
- }
- }
- AppendPascalString(work, "\p =");
- cmdBlockLength = SCSIGetCommandLength((Ptr) scsiCommand);
- if (cmdBlockLength == 0)
- cmdBlockLength = sizeof (SCSI_Command);
- for (i = 0; i < cmdBlockLength; i++) {
- AppendChar(work, ' ');
- AppendHexLeadingZeros(work, (unsigned long) scsiCommand->scsi[i], 2);
- }
- LOG(work);
- }
-
-
- void
- AppendDeviceID(
- StringPtr result,
- DeviceIdent scsiDevice
- )
- {
- AppendUnsigned(result, scsiDevice.bus);
- AppendChar(result, '.');
- AppendUnsigned(result, scsiDevice.targetID);
- AppendChar(result, '.');
- AppendUnsigned(result, scsiDevice.LUN);
- }
-
-